﻿using SPWebShell.entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Web.Services.Protocols;

namespace SPWebShell.cmdlet
{
    /// <summary>
    /// Gets a listing of all subsites at the specified URL. (recursive option also provided)
    /// </summary>
    [Cmdlet(VerbsCommon.Get, "SPWebs")]
    public class GetSPWebs : CmdLetBase
    {

        public GetSPWebs()
        {
            this.Recurse = false;
        }
        
        [Parameter(Mandatory = true, HelpMessage="The absolute URL to the SharePoint site collection. e.g. http://server/sites/SiteA/")]
        [ValidateNotNullOrEmpty]
        public string Url { get; set; }

        [Parameter(Mandatory = false, HelpMessage = "When set to True, all descendant sites are obtained. Default is False" )]
        [Alias("recursive")]
        public bool Recurse { get; set; }

        protected override void ProcessRecord()
        {
            try
            {
                VerboseLogger("Start time: " + DateTime.Now.ToString());
                VerboseLogger (string.Format("Url:{0},Recurse:{1}",this.Url,this.Recurse) );
                ISPRepository repos = base.SPRepos;
                VerboseLogger("Resolving container site from supplied URL");
                string urlContainerSite=repos.GetContainerWebFromDocLibUrl(this.Url);
                VerboseLogger("Container url:" + urlContainerSite);
                List<SPWeb> masterlist = new List<SPWeb>();
                Action<string> fnRecurse = null;
                fnRecurse=delegate(string url)
                {
                    VerboseLogger(string.Format("Enumerating websites under:{0}", url));
                    SPWeb[] webs = repos.GetWebs(url);
                    foreach (SPWeb web in webs)
                    {
                        if (!web.Url.EndsWith("/")) web.Url = web.Url + "/";
                        masterlist.Add(web);
                        fnRecurse(web.Url);
                    }
                };
                if (this.Recurse)
                {
                    fnRecurse(urlContainerSite);
                }
                else
                {
                    SPWeb[] webs = repos.GetWebs(urlContainerSite);
                    foreach (SPWeb web in webs)
                    {
                        masterlist.Add(web);
                    }
                }
                
                foreach (SPWeb web in masterlist)
                {
                    WriteObject(web);
                }
                base.ProcessRecord();
            }
            catch (SoapException ex)
            {
                string message = ex.Detail.OuterXml;
                throw new Exception(message, ex);
            }
            finally
            {
                WriteVerbose("End time: " + DateTime.Now.ToString());
            }
        }
    }
}
